package org.zaproxy.zap.view.widgets;
import java.awt.Component;
import java.util.List;
import javax.swing.ComboBoxModel;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JComboBox;
import javax.swing.JList;
import javax.swing.border.Border;
import javax.swing.border.EmptyBorder;
import javax.swing.plaf.basic.BasicComboBoxRenderer;
import org.parosproxy.paros.model.Model;
import org.parosproxy.paros.model.Session;
import org.zaproxy.zap.model.Context;
/**
* A ComboBox widget that displays the list of existing {@link Context Contexts}.
* <p>
* <strong>NOTE:</strong> Does not automatically refresh when the Contexts have changed. For this, make sure you
* manually call {@link #reloadContexts(boolean)}.
*/
public class ContextSelectComboBox extends JComboBox<Context> {
private static final long serialVersionUID = 6177823947839642740L;
@SuppressWarnings("unchecked")
public ContextSelectComboBox() {
super();
reloadContexts(false);
this.setRenderer(new ContextComboBoxRenderer());
}
/**
* Reloads/refreshes the list of {@link Context Contexts} from the {@link Session}.
*
* @param keepSelected whether the previously selected context is tried to be restored. If
* {@code false}, defaults to no selection.
*/
public void reloadContexts(boolean keepSelected) {
Context selected = null;
if (keepSelected)
selected = (Context) getSelectedItem();
List<Context> contexts = Model.getSingleton().getSession().getContexts();
Context[] contextsArray = contexts.toArray(new Context[contexts.size()]);
ComboBoxModel<Context> model = new DefaultComboBoxModel<>(contextsArray);
// No matter what, set selected item, so it either defaults to 'nothing selected' or
// restores the previously selected item
model.setSelectedItem(selected);
this.setModel(model);
}
/**
* Returns the selected {@link Context}. Behaves the same as {@link #getSelectedItem()}, but
* performs a cast.
*
* @see #getSelectedItem()
* @return the selected context, if any
*/
public Context getSelectedContext() {
return (Context) getSelectedItem();
}
/**
* A renderer for properly displaying the name of Context in a ComboBox.
*/
private static class ContextComboBoxRenderer extends BasicComboBoxRenderer {
private static final Border BORDER = new EmptyBorder(2, 8, 2, 8);
private static final long serialVersionUID = 3272133514462699823L;
@Override
@SuppressWarnings("rawtypes")
public Component getListCellRendererComponent(JList list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value != null) {
Context item = (Context) value;
setText(item.getName());
setBorder(BORDER);
}
return this;
}
}
}